package config

import (
	"FastDevelopGo/src/base/util"
	"bufio"
	"flag"
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	"os"
	"strings"
)

var (
	SysConfigDir      string
	SysConfigName     string
	SysConfigType     string
	SysConfigFilePath string
)

func InitConfig() error {
	SysConfigDir = *flag.String("d", "./conf/", "配置一个启动配置文件存放目录，默认：./conf/")
	SysConfigName = *flag.String("n", "sys", "配置启动配置文件名称，默认：sys")
	SysConfigType = *flag.String("t", "toml", "配置启动配置文件类型，默认：toml")
	flag.Parse()
	// 初始赋值配置文件地址
	SysConfigFilePath = SysConfigDir + "/" + SysConfigName + "." + SysConfigType
	// 加载启动配置
	if configLoad() {
		// 配置加载正常，可以继续向下进行
		return nil
	} else {
		return fmt.Errorf("发生了一个致命错误，程序结束 \n")
	}
}

//configLoad 配置文件加载内部函数
func configLoad() (state bool) {
	// 设定读取名称
	viper.SetConfigName(SysConfigName)
	// 设定配置文件类型
	viper.SetConfigType(SysConfigType)
	// 设定扫描目录
	viper.AddConfigPath(SysConfigDir)
	// 设置默认配置
	viper.SetDefault("sys", map[string]string{
		"conf_type": "toml",
		"conf_dir":  "conf/app",
		"conf_name": "base",
	})
	// 读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			reader := bufio.NewReader(os.Stdin)
			fmt.Println("没有找到配置文件，请选择启动方式（1、2、3、）")
			fmt.Println("1、自动创建配置文件与文件夹并启动")
			fmt.Println("2、不创建配置文件，直接依据默认配置启动")
			fmt.Println("3、退出")
			fmt.Print("-> ")
			isContinue, err := reader.ReadString('\n')
			if err != nil {
				state = false
				panic(fmt.Errorf("发生致命错误: %w \n", err))
			} else {
				// 转换为小写并去除前后空格
				isContinue = strings.TrimSpace(strings.ToLower(isContinue))
				// 判断输入是否正确
				if isContinue == "1" || isContinue == "1、" || isContinue == "1." {
					// 根据是否存在目录进行创建需要的目录
					if _, err := util.IsExistAndCreateDir(SysConfigDir); err == nil {
						// 2、进行创建需要的配置文件
						err := viper.WriteConfigAs(SysConfigFilePath)
						if err != nil {
							state = false
							panic(fmt.Errorf("致命错误：%w \n", err))
						} else {
							state = true
						}
					} else {
						state = false
						panic(fmt.Errorf("创建文件夹时发生致命错误：%w \n", err))
					}
				} else if isContinue == "2" || isContinue == "2、" || isContinue == "2." {
					// 直接使用默认配置，不再生成配置文件，由于上述默认已经在最初时初始化了，因此不需要再进行重复操作
					state = true
				} else {
					// 退出
					state = false
				}
			}
		} else {
			state = false
			// 找到配置文件，但产生了另一个错误
			panic(fmt.Errorf("配置文件致命错误: %w \n", err))
		}
	} else {
		state = true
	}
	// 观察配置文件是否被变更
	viper.OnConfigChange(func(e fsnotify.Event) {
		fmt.Println("Config file changed:", e.Name)
	})
	// 配置文件被修改时再次读取
	viper.WatchConfig()
	fmt.Println(viper.Get("sys.conf_dir"))
	fmt.Println(viper.Get("sys.conf_type"))
	fmt.Println(viper.Get("sys.conf_name"))
	return state
}
